<?php

namespace Lib\Base;

use Lib\Cache\RedisAction;

class Response
{

    public static $response;

    /**
     * init
     *
     * @param $request
     */
    public static function init($response)
    {
        if (isSwoole()) {
            $requestId = \Swoole\Coroutine::getuid();
            self::$response[$requestId] = $response;
        }
    }

    /**
     * outputJson
     *
     * @param $data
     * @return bool
     */
    public static function outputJson($data)
    {
        try {
            // 返回JSON数据格式到客户端 包含状态信息
            $data = json_encode($data);
            if ($data === false) {
                throw new \Exception(json_last_error_msg());
            }

            if (isSwoole()) {
                $requestId = \Swoole\Coroutine::getuid();
                self::$response[$requestId]->header('Access-Control-Allow-Origin', Request::getRequest()->header['origin'] ?? '', true);
                self::$response[$requestId]->header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept', true);
                self::$response[$requestId]->header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS', true);
                self::$response[$requestId]->header('Access-Control-Allow-Credentials', 'true', true);
                self::$response[$requestId]->end($data);

                //阻断没加return程序往下运行
                throw new \Lib\Exception\OutputException("request end after outputJSON", -1003);

                return false;
            } else {
                echo $data;
                exit();
            }
        } catch (\Exception $e) {
            throw $e;
        }
    }

    public static function outputJsonp($data)
    {
        try {
            $jsonpHandler = Request::param('callback');

            /*对callback函数名字进行校验，防止XSS(UTF-7)*/
            if (!preg_match('/^[_a-zA-Z][\da-zA-Z_]+$/', $jsonpHandler)) {
                $jsonpHandler = 'callback';
            }

            $data = json_encode($data);
            if ($data === false) {
                throw new \Exception(json_last_error_msg());
            }

            if (isSwoole()) {

                $requestId = \Swoole\Coroutine::getuid();
                self::$response[$requestId]->header('Access-Control-Allow-Origin', Request::getRequest()->header['origin'] ?? '', true);
                self::$response[$requestId]->header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept', true);
                self::$response[$requestId]->header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS', true);
                self::$response[$requestId]->header('Access-Control-Allow-Credentials', 'true', true);
                self::$response[$requestId]->end($jsonpHandler . '(' . $data . ');');

                //阻断没加return程序往下运行
                throw new \Lib\Exception\OutputException("request end after outputJSON", -1003);

                return false;
            } else {
                echo $jsonpHandler . '(' . $data . ');';
                exit();
            }
        } catch (\Exception $e) {
            throw $e;
        }
    }

    public static function outputHeader($data, $header)
    {
        if (is_array($header)) {
            foreach ($header as $value) {
                header($value);
            }
        }
        echo $data;
        exit();
    }

    /**
     * 析构方法
     */
    public static function destruct()
    {
        if (isSwoole()) {
            $requestId = \Swoole\Coroutine::getuid();
            if ($requestId > 0 && isset(self::$response[$requestId])) {
                unset(self::$response[$requestId]);
            }
        }
    }

    /**
     * 获取response对象
     *
     * @return null
     */
    public static function getResponse()
    {
        if (isSwoole()) {
            $requestId = \Swoole\Coroutine::getuid();
            return self::$response[$requestId];
        } else {
            return null;
        }
    }

    /**
     * SWoole outputJson 系统内调用，开发不要用
     *
     * @param $data
     * @return bool
     */
    public static function swooleSystemOutputJson($iRet, $sMsg, $jData = [])
    {
        $cgiStartTime = Request::getParam('cgiStartTime');

        //结束时间
        $cgiEndTime = microtime(true);

        $redata = [
            'iRet' => $iRet,
            'sMsg' => $sMsg,
            'jData' => $jData,
            'sSerial' => Request::getParam("sAmsSerial"),
            'execTime' => round((($cgiEndTime - $cgiStartTime) * 1000), 3)
        ];
        $data = json_encode($redata);
        $requestId = \Swoole\Coroutine::getuid();
        self::$response[$requestId]->header('Access-Control-Allow-Origin', Request::getRequest()->header['origin'] ?? '', true);
        self::$response[$requestId]->header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept', true);
        self::$response[$requestId]->header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS', true);
        self::$response[$requestId]->header('Access-Control-Allow-Credentials', 'true', true);
        self::$response[$requestId]->end($data);
        RedisAction::destruct();
        Request::destruct();
        Response::destruct();
        return false;
    }
}
